package com.yskj.mwk.controller;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yskj.mwk.bean.OrdersRefund;
import com.yskj.mwk.config.WechatUrlConfig;
import com.yskj.mwk.config.WxpayConfig;
import com.yskj.mwk.service.ManagerService;
import com.yskj.mwk.service.UserService;
import com.yskj.mwk.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("wxPay")
public class WxPayController {

    private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private ManagerService managerService;

    /**
     * 微信退款回调
     *
     * @param body
     * @param request
     * @return
     */
    @PostMapping("/wxRefoundCallback")
    public Map wxRefoundCallback(@RequestBody Map body, HttpServletRequest request) {
        Map<String, Object> result = new HashMap();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map<String, String> resource = (Map) body.get("resource");
            logger.info("【微信退款回调】解密后的数据: {}", resource);
            //回调报文解密
            AesUtil aesUtil = new AesUtil(WxpayConfig.v3Key.getBytes());
            //解密后json字符串
            String decryptToString = aesUtil.decryptToString(
                    resource.get("associated_data").getBytes(),
                    resource.get("nonce").getBytes(),
                    resource.get("ciphertext"));
            //微信退款返回的信息
            Map<String, Object> jsonData = objectMapper.readValue(decryptToString, Map.class);
            logger.info("【微信退款回调】解密后的数据: {}", jsonData);
            //退款成功
            if ("SUCCESS".equals(jsonData.get("refund_status"))) {
                //退款单号
                String outRefundNo = jsonData.get("out_refund_no").toString();
                //微信退款单号
                String refundId = jsonData.get("refund_id").toString();
                //调取查询接口判断是否退款到账如果到账则修改状态
                JsonNode JSON = WxHttpUtils.doGet("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/"+outRefundNo);
                JsonNode statusNode = JSON.get("status");
                JsonNode refundidNode=JSON.get("refund_id");
                if (statusNode != null) {
                    logger.info("【微信退款回调】退款状态: {},退款编号：{}", statusNode.asText(),refundidNode.asText());
                    String tradeState = statusNode.asText();
                    String refund_id=refundidNode.asText();
                    if(tradeState.equals("SUCCESS")){
                        managerService.updateAfterStatus(refund_id);
                    }
                } else {

                }
            }
            result.put("code", "SUCCESS");
            result.put("message", "成功");
        } catch (Exception e) {
            result.put("code", "fail");
            result.put("message", "系统错误");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 支付回调
     *
     * @param body    应答的报文主体
     * @param request 应答数据
     * @return
     */
    @PostMapping("/wxPayCallback")
    public Map wxPayCallback(@RequestBody Map body, HttpServletRequest request) {
        Map<String, Object> result = new HashMap();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map<String, String> resource = (Map) body.get("resource");
            //回调报文解密
            AesUtil aesUtil = new AesUtil(WxpayConfig.v3Key.getBytes());
            //解密后json字符串
            String decryptToString = aesUtil.decryptToString(
                    resource.get("associated_data").getBytes(),
                    resource.get("nonce").getBytes(),
                    resource.get("ciphertext"));
            //微信支付返回的信息
            Map<String, Object> jsonData = objectMapper.readValue(decryptToString, Map.class);

            logger.info("【微信支付回调】解密后的数据: {}", jsonData);
            //支付成功
            if ("SUCCESS".equals(jsonData.get("trade_state"))) {
                //交易订单号,自己生成的订单号
                String outTradeNo = jsonData.get("out_trade_no").toString();
                //微信订单号
                String transactionId = jsonData.get("transaction_id").toString();
                String attach = jsonData.get("attach").toString();

                userService.wxPayCallbackUpdateOrderStatus(outTradeNo,attach,transactionId,outTradeNo);
                logger.info("【微信支付回调】支付成功，订单号: {}, 微信订单号: {}", outTradeNo, transactionId);
            } else {
                logger.info("【微信支付回调】支付状态: {}", jsonData.get("trade_state"));
            }
//            else if ("NOTPAY".equals(jsonData.get("trade_state"))||"CLOSED".equals(jsonData.get("trade_state"))) {
//                String outTradeNo = jsonData.get("out_trade_no").toString();
//                String attach = jsonData.get("attach").toString();
//                userService.updateSysOrderStatus(outTradeNo,Integer.parseInt(attach));
//            }
            result.put("code", "SUCCESS");
            result.put("message", "成功");
        } catch (Exception e) {
            result.put("code", "fail");
            result.put("message", "系统错误");
            logger.error("【微信支付回调】处理异常", e);
        }
        return result;
    }

    /**
     * 下单,返回给前端支付
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/submitWxOrder")
    public JsonResult wxPay(@RequestParam("openId") String openId,@RequestParam("payType") int payType,@RequestParam("orderId") String orderId) throws Exception {
        //查看当前订单是否支付
        boolean isPay= userService.checkOrderIsPay(orderId,payType);
        logger.info("【微信支付下单】下单单号: {}；下单种类：{}；状态：{}", orderId,payType,isPay);
        if (!isPay) {
            Map<String, Object> map = new HashMap();
            map.put("appid", WxpayConfig.appId);
            map.put("mchid", WxpayConfig.mchId);
            map.put("description", "小鹅定制商品");
            map.put("attach", payType + "");
            map.put("out_trade_no", orderId);
            map.put("notify_url", WxpayConfig.notifyOrderUrl);
            Map<String, Object> amount = new HashMap();
            //根据订单编号查询订单应支付金额
            long totalFen = userService.getOrdertotalPriceByOrderId(orderId, payType);
            //订单金额 单位分
            amount.put("total", totalFen);
            amount.put("currency", "CNY");
            map.put("amount", amount);
            // 设置小程序所需的openid
            Map<String, Object> payermap = new HashMap();
            payermap.put("openid", openId);
            map.put("payer", payermap);
            ObjectMapper objectMapper = new ObjectMapper();
            String body = objectMapper.writeValueAsString(map);
            logger.info("【微信支付下单】下单body: {}", body);
            Map<String, Object> stringObjectMap = WxHttpUtils.doPostWexin(WechatUrlConfig.JSAPI_ORDER, body);
            if (stringObjectMap != null) {
                userService.updateSysOrderStatus(orderId, payType);
                return ResultUtils.success("获取成功", WeixinchatPayUtils.getTokenJSAPI(WxpayConfig.appId, String.valueOf(stringObjectMap.get("prepay_id"))));
            } else {
                return ResultUtils.failure(501, "系统异常");
            }
        }else{
            return ResultUtils.failure(101, "该订单已支付");
        }
    }

    /**
     * 根据订单号获取订单是否支付完成
     * */
    @PostMapping("/queryOrderIsPay")
    public JsonResult queryOrderIsPay(@RequestParam("orderId") String orderId,@RequestParam("payType") int payType){
        JsonNode JSON = WxHttpUtils.doGet("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+orderId+"?mchid="+WxpayConfig.mchId);
        JsonNode tradeStateNode = JSON.get("trade_state");
        JsonNode transactionidNode = JSON.get("transaction_id");
        JsonNode outtradenoNode = JSON.get("out_trade_no");
        if (tradeStateNode != null) {
            String tradeState = tradeStateNode.asText();
            String out_trade_no=outtradenoNode.asText();
            if(tradeState.equals("SUCCESS")){
                userService.wxPayCallbackUpdateOrderStatus(orderId,payType+"",transactionidNode.asText(),out_trade_no);
            }
        } else {
            System.out.println("trade_state field not found");
        }
        System.out.println(JSON);
        return  ResultUtils.success("获取成功",JSON);
    }

    /**
     * 申请退款
     *
     * @return
     */
    @PostMapping("/applyRefund")
    public JsonResult applyRefund(@RequestParam("orderId") String orderId,@RequestParam("refundTotal") double refundTotal,@RequestParam("out_trade_no") String out_trade_no) throws Exception {
        //1.退款之前先查看此订单是否支付
        //2.退款金额是不是小于等于可退款订单金额
        int result=managerService.checkOrderIsCanRefund(orderId,refundTotal);
        if(result==0){
            //可以发起退款
            Map<String, Object> map = new HashMap();
            //当前退款订单号码,随机生成,唯一
            OrderNumberGenerator orderNumberGenerator = new OrderNumberGenerator();
            String out_refund_no=orderNumberGenerator.generateOrderNumber();
            map.put("out_refund_no", out_refund_no);
            //订单号,用户下单时候订单
            map.put("out_trade_no", out_trade_no);
            ObjectMapper objectMapper = new ObjectMapper();
            //构建订单信息
            Map<String, Object> amountMap = new HashMap();
            int refund=managerService.getFen(orderId,refundTotal,2);
            int total=managerService.getFen(orderId,refundTotal,1);
            amountMap.put("refund", refund);
            amountMap.put("total", total);
            amountMap.put("currency", "CNY");
            map.put("amount", amountMap);
            map.put("notify_url", WxpayConfig.notifyRefoundUrl);
            String body = objectMapper.writeValueAsString(map);
            Map<String, Object> stringObjectMap = WxHttpUtils.doPostWexin(WechatUrlConfig.JSAPI_REFUND_ORDER, body);
            if (stringObjectMap!=null){
                String refund_id=String.valueOf(stringObjectMap.get("refund_id"));
                OrdersRefund ordersRefund = new OrdersRefund();
                ordersRefund.setOrderId(orderId);
                ordersRefund.setRefund_id(refund_id);
                ordersRefund.setOut_refund_no(out_refund_no);
                ordersRefund.setRefundTotal(refund);
                ordersRefund.setOrderTotal(total);
                ordersRefund.setStatus(1);
                ordersRefund.setOut_trade_no(out_trade_no);
                int res=managerService.saveRefunLogsToSql(ordersRefund);
                if (res>0){
                    return  ResultUtils.success("发起成功",null);
                }else{
                    return  ResultUtils.failure(502,"系统异常");
                }
            }else{
                return  ResultUtils.failure(501,"系统异常");
            }
        }else if(result==101){
            return  ResultUtils.failure(101,"订单不存在");
        }
        else if(result==102){
            return  ResultUtils.failure(102,"订单未支付");
        }
        else if(result==103){
            return  ResultUtils.failure(103,"当前申请退款的金额高于订单可退款金额");
        }
        return null;
    }
}
